package Z11_3_ReentrantLock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author： pang-yun
 * @date： 2021-11-01 11:57
 * 功能目的 ：用于  最终版本   为了防止 错误唤醒  在其中加上  while  判断    如果不是  就继续 wait
 * <p>
 * 使用 ReentrantLock
 */

@Slf4j
public class TestModifyFinal {
    static final Object room = new Object();
    static boolean hasCigarette = false;
    static boolean hasTakeout = false;
    static ReentrantLock ROOM = new ReentrantLock();
    //
    static Condition cigaretteRoom = ROOM.newCondition();
    static Condition takeoutRoom = ROOM.newCondition();

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            ROOM.lock();
            try {
                log.info(" has  cigarette? {}", hasCigarette);
                while (!hasCigarette) {
                    log.info("no ! give me a break");
                    try {
                        cigaretteRoom.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.info(" now   has Cigarette? {}", hasCigarette);

                if (hasCigarette) {
                    log.info("now  root begin working!");
                }
            } finally {
                ROOM.unlock();
            }
        }, "吸烟 thread").start();


        new Thread(() -> {
            ROOM.lock();
            try {
                log.info(" has  takeout? {}", hasTakeout);
                while (!hasTakeout) {
                    log.info("no ! give me a break");
                    try {
                        takeoutRoom.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.info(" now   has takeout? {}", hasTakeout);

                if (hasTakeout) {
                    log.info("now  外卖  begin working!");
                }
            } finally {
                ROOM.unlock();
            }
        }, "外卖 thread").start();


        // 主线程 阻塞 一段时间后 开启 送外卖 线程
        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            ROOM.lock();
            try {
                hasTakeout = true;
                log.info("开始送外卖");
                // room.notify();   只能唤醒 随机  一个   可能存在 唤醒错误
                //room.notifyAll();  // 唤醒所有的    总能找到   正确的
                cigaretteRoom.signalAll();
                takeoutRoom.signalAll();

            } finally {
                ROOM.unlock();
            }
        }, "外卖员！").start();

    }

}
